#include "PatchStomper/StomperModel.h"
#include "PatchStomper/ToolElements/TextureTool.h"
#include "StompedReality/Asset/AssetManager.h"
#include "StompedReality/Core/FileSystem.h"
#include "StompedReality/Core/Graphics/RenderSystem.h"
#include "StompedReality/Core/IGame.h"
#include "StompedReality/Core/Input/Keys.h"
#include "StompedReality/Math/Rectangle.h"
#include "StomperLib/Controls/ToolSet.h"
#include "StomperLib/Controls/ToolWindow.h"
#include "StomperLib/Objects/RectPatchObject.h"
#include "StomperLib/RenderHelper.h"
#include <gl\GL.h>
namespace PatchStomper {
TextureTool::TextureTool( StomperLib::BaseLayout* layout, StompedReality::IGame* game,
                          StomperLib::EditorCamera* camera )  : StomperLib::ToolElement( layout, game, camera )
{
  m_TextureInfo = NULL;
  this->CreateGui( layout );

  this->SelectionFunction = [&]( StomperLib::EditorObjectInfo* object )->bool
  {
    auto patchObj = (StomperLib::RectPatchObject*) object;
    return StompedReality::Math::Rectangle::Contains( patchObj->Pos, patchObj->Size, this->GetMousePos( ));
  };
}

TextureTool::~TextureTool( )
{
}

void TextureTool::OnOpenTexture( Gwen::Event::Info information )
{
  PatchStomper::StomperModel* data = (PatchStomper::StomperModel*)Model;
  if (m_TextureInfo)
  {
    glDeleteTextures( 1, &(m_TextureInfo->glBinding) );
    delete m_TextureInfo;
    m_TextureInfo = NULL;
    data->TextureSize = StompedReality::Math::Vector2( 0, 0 );
  }

  m_TextureInfo = new StompedReality::Asset::TextureInfo( );

  std::string absTextureFile = this->m_Game->getFileSystem( )->getBasePath( );
  absTextureFile.append( "/" ).append( information.String.c_str( ));

  this->m_Game->getAssetManager( )->OpenTexture( *m_TextureInfo, absTextureFile.c_str( )); //information.String.c_str( ));

  data->TextureSize = StompedReality::Math::Vector2( m_TextureInfo->width, m_TextureInfo->height );

  this->ResetCamera( );
}

void TextureTool::Draw( )
{
  if (!m_TextureInfo)
    return;

  this->RenderTexture( );
}

bool TextureTool::Update( )
{
  if (GetInputSystem( )->IsRightButtonPressed( ))
  {
    this->m_Camera->Translate( GetInputSystem( )->GetMouseDelta( ));
  }

  return false;
}

void TextureTool::CreateGui( StomperLib::BaseLayout* layout )
{
  auto window = layout->CreateSubWindow( "Tools", "Ctrl + Shift + t", true );
  StomperLib::Controls::ToolSet* tools = new StomperLib::Controls::ToolSet( window );
  tools->InitRows( 3 );

  // first row
  Gwen::Controls::Button* selectButton = tools->AddButton( "SelectButton", "EditorBase/img/select.png", "Select", 0, 0 );
  selectButton->onToggleOn.Add( this, &TextureTool::OnSelectToolActivate );
  selectButton->AddAccelerator( "q" );
  selectButton->SetToggleState( true );

  Gwen::Controls::Button* deletePatchButton =
    tools->AddButton( "DeleteButton", "EditorBase/img/delete.png", "Delete Patch", 0,
                      1 );
  deletePatchButton->onToggleOn.Add( this, &TextureTool::OnDeleteToolActivate );
  deletePatchButton->AddAccelerator( "w" );

  // second row
  Gwen::Controls::Button* translatePatchButton =
    tools->AddButton( "TranslateButton", "EditorBase/img/translate.png", "Translate Patch", 1,
                      0 );
  translatePatchButton->onToggleOn.Add( this, &TextureTool::OnTranslationToolActivate );
  translatePatchButton->AddAccelerator( "a" );

  Gwen::Controls::Button* rotatePatchButton =
    tools->AddButton( "RotateButton", "EditorBase/img/rotation.png", "Rotate Patch", 1,
                      1 );
  rotatePatchButton->onToggleOn.Add( this, &TextureTool::OnRotateToolActivate );
  rotatePatchButton->AddAccelerator( "s" );

  Gwen::Controls::Button* resizePatchButton =
    tools->AddButton( "ResizeButton", "EditorBase/img/resize.png", "Resize Patch", 1,
                      2 );
  resizePatchButton->onToggleOn.Add( this, &TextureTool::OnResizeToolActivate );
  resizePatchButton->AddAccelerator( "d" );

  // 3rd row
  Gwen::Controls::Button* rectPatchButton =
    tools->AddButton( "RectangleButton", "Content/img/rectangle.png", "Add Rectangle Patch", 2,
                      0 );
  rectPatchButton->onToggleOn.Add( this, &TextureTool::OnRectangleToolActivate );
  rectPatchButton->AddAccelerator( "y" );

  Gwen::Controls::Button* addPatchByGridButton =
    tools->AddButton( "AddByGridButton", "Content/img/grid.png", "Add by Grid", 2,
                      1 );
  addPatchByGridButton->onToggleOn.Add( this, &TextureTool::OnAddByGridButton );
  addPatchByGridButton->onToggleOff.Add( this, &TextureTool::OnNotAddByGridButton );
  addPatchByGridButton->AddAccelerator( "x" );

  layout->onMouseEditAreaEnter.Add( window, &StomperLib::Controls::ToolWindow::EnableAccelerator );
  layout->onMouseEditAreaLeave.Add( window, &StomperLib::Controls::ToolWindow::DisableAccelerator );
}

void TextureTool::OnSelectToolActivate( )
{
  this->SetMode( SelectMode  );
}

void TextureTool::OnRectangleToolActivate( )
{
  this->SetMode( RectPatchMode );
}

void TextureTool::OnAddByGridButton( )
{
  m_WasGridActive = ((PatchStomper::StomperModel*)Model)->GridActive;
  ((PatchStomper::StomperModel*)Model)->GridActive = true;
  this->SetMode( GridClickAddPatchMode );
}

void TextureTool::OnNotAddByGridButton( )
{
  ((PatchStomper::StomperModel*)Model)->GridActive = m_WasGridActive;
}

void TextureTool::OnDeleteToolActivate( )
{
  this->SetMode( DeletePatchMode );
}

void TextureTool::SetMode( int mode )
{
  Model->Mode = mode;
}

void TextureTool::OnTranslationToolActivate( )
{
  this->SetMode( TranslateMode );
}

void TextureTool::OnRotateToolActivate( )
{
  this->SetMode( RotateMode );
}

void TextureTool::OnResizeToolActivate( )
{
  this->SetMode( ResizeMode );
}

void TextureTool::RenderTexture( )
{
  glColor3f ( 1, 1, 1 );
  glBindTexture ( GL_TEXTURE_2D, m_TextureInfo->glBinding );
  glBegin ( GL_TRIANGLE_STRIP );
  glTexCoord2f ( 0, 1 );
  glVertex2f ( 0, m_TextureInfo->height );
  glTexCoord2f ( 1, 1 );
  glVertex2f ( m_TextureInfo->width, m_TextureInfo->height );
  glTexCoord2f ( 0, 0 );
  glVertex2f ( 0, 0 );
  glTexCoord2f ( 1, 0 );
  glVertex2f ( m_TextureInfo->width, 0 );
  glEnd( );
  glBindTexture ( GL_TEXTURE_2D, 0 );
}

void TextureTool::ResetCamera( )
{
  int width = this->GetGame( )->RenderSystem( )->GetWidth( );
  int height = this->GetGame( )->RenderSystem( )->GetHeight( );

  int offX = (width > this->m_TextureInfo->width) ? (width - this->m_TextureInfo->width)/2 : 50;
  int offY = (height > this->m_TextureInfo->height) ? (height - this->m_TextureInfo->height)/2 : 50;

  this->m_Camera->Reset( offX, offY );
}

}